package com.one.blocks.rbac.listener;

import com.one.blocks.rbac.enums.CacheEventEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <a href="mailto:idler41@163.con">linfuxin</a> created on 2022-12-07 15:23:05
 */
@Component
@Slf4j
public class CacheListener implements ApplicationContextAware {

    private Map<CacheEventEnum, List<CacheClearHandler>> handlerMap;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, CacheClearHandler> handlerBeanMap = applicationContext.getBeansOfType(CacheClearHandler.class);
        if (handlerBeanMap.isEmpty()) {
            handlerMap = Collections.emptyMap();
            log.warn("cacheEvent处理器为空!");
            return;
        }
        handlerMap = new HashMap<>(handlerBeanMap.size());
        for (CacheClearHandler cacheHandler : handlerBeanMap.values()) {
            for (CacheEventEnum cacheEventEnum : cacheHandler.support()) {
                List<CacheClearHandler> handlerList = handlerMap.get(cacheEventEnum);
                if (CollectionUtils.isEmpty(handlerList)) {
                    handlerList = new ArrayList<>();
                    handlerMap.put(cacheEventEnum, handlerList);
                }
                handlerList.add(cacheHandler);
            }

        }
    }

    @EventListener(CacheClearEvent.class)
    public void onCacheEvent(CacheClearEvent cacheEvent) {
        for (CacheEventEnum eventType : cacheEvent.getEventTypes()) {
            if (handlerMap.containsKey(eventType)) {
                for (CacheClearHandler cacheHandler : handlerMap.get(eventType)) {
                    cacheHandler.clearCache(eventType);
                }
            }
        }
    }
}
